import javax.crypto.Cipher;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.io.ByteArrayInputStream;
import java.util.Arrays;
import java.util.Base64;

/**
 * 测试RSA加密解密循环
 */
public class TestRSAEncryptDecrypt {
    
    private static final String CERT_BASE64 = 
        "MIIC6DCCAdCgAwIBAgIGAZlhQblOMA0GCSqGSIb3DQEBCwUAMDUxCzAJBgNVBAYT" +
        "AkNOMRAwDgYDVQQKEwdFeGFtcGxlMRQwEgYDVQQDEwtTZWxmLVNpZ25lZDAeFw0y" +
        "NTA5MTkwOTE1MjFaFw0yNjA5MTkwOTE1MjFaMDUxCzAJBgNVBAYTAkNOMRAwDgYD" +
        "VQQKEwdFeGFtcGxlMRQwEgYDVQQDEwtTZWxmLVNpZ25lZDCCASIwDQYJKoZIhvcN" +
        "AQEBBQADggEPADCCAQoCggEBALPwnK6bMFFHWeN3E/MIWmpZesBQGILjJxNtMN1Z" +
        "2lmRyLCJdTmz87EXmLuX4e/Bz0aCOmH88qjs+laHFmnPIQal3rJU32MCMk63bejZ" +
        "N6yArwv8MAyF0kvyA3EoBC6ZsYX55sxtxLyNYvG8MCqmacRbxV0IsSMXq6o4+1wO" +
        "YiQEXzdbqhp67fYPNOv81LXqxQZArGV+Wj2o86XtW1wixtHnaSUori4jJjbe1YKi" +
        "6LIbzhz9SK34+V4PkRhQYS7ensgAAbm4k3N5R3RSNkOHLrHu576QaBwKYI1DjNJL" +
        "9tAcySdqXColS9RLG0h/x2r78Pvybt3hm32f1kPbu3hnaMcCAwEAATANBgkqhkiG" +
        "9w0BAQsFAAOCAQEApMy1ilW+EsqQZ+2VMyvmQgjfqoaat5kvNqdluLwtzISuY/dv" +
        "1V2ccR3eShnta7hKO1WCT1WF3L31MLtDwWw/VEiWFDu3+H/9P9nWr7w6ocGVWCUw" +
        "UoZwiJk5DuBKZYlmj8LgjAKk6bh3hi7Fs3Kbct1rLXUtL0wiqRF7y49tnjWKiEOz" +
        "gIeHQnS6m2geS1aEpUQlsEm8vUanNuAmnWJppMpfJuWQ7XDPZfRDelyepkefWSdO" +
        "td3RKKWGhk70KM00Scmav4mrUYE1K8xIXUvYrc2ECpyvuJjZ6masXzoTRGN+bEvl" +
        "OML/U6TTbXIttbqqnNe9iLrszUStBXjGkpJohA==";
    
    private static final String PRIVATE_KEY_PEM = 
        "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCz8JyumzBRR1nj" +
        "dxPzCFpqWXrAUBiC4ycTbTDdWdpZkciwiXU5s/OxF5i7l+Hvwc9Ggjph/PKo7PpW" +
        "hxZpzyEGpd6yVN9jAjJOt23o2TesgK8L/DAMhdJL8gNxKAQumbGF+ebMbcS8jWLx" +
        "vDAqpmnEW8VdCLEjF6uqOPtcDmIkBF83W6oaeu32DzTr/NS16sUGQKxlflo9qPOl" +
        "7VtcIsbR52klKK4uIyY23tWCouiyG84c/Uit+PleD5EYUGEu3p7IAAG5uJNzeUd0" +
        "UjZDhy6x7ue+kGgcCmCNQ4zSS/bQHMknalwqJUvUSxtIf8dq+/D78m7d4Zt9n9ZD" +
        "27t4Z2jHAgMBAAECggEAAr15RVdrpvE1NzeLADpyVghCzEbr+KJI6AzTn6tMneyQ" +
        "Z8/QDy7kWSAI3WJ0uFf1Nhepl/BoKZZiQYsRFk9nK1i/SWvtcu6HoZc9fzw/ksrq" +
        "333ZpXcsOqfW0ZRQa/0/LNEfaKGLS2vDw/afrSaXmbvkB4SoXeZwYMk5Wq+FYxL/" +
        "alrNpg/lzdvBlsCsTDA0G2RZrUVaO5yRTLRisBU+i8yORgnGkEwWvKpZYSFogCHS" +
        "iYHiNXFy//C+sYWlK7DjmG8/+krKhqBRRfdeg7LFThHQpbEGTtueD57jw0PCo2yr" +
        "6dqTvW9Qys+aWVNJk7RHNaI0yBFKWPadaHi3/olzkQKBgQDmz/FDpztS0fjKDIOj" +
        "gDyE76Z6dRFenmKJM1eOFt+MniY6/vi4ylU51/Etm4k6dNJ1MVBoFfyT9X0U/4k7" +
        "GNNUfIxMCJztUgY6EaCCt+09wk8pIvmOlRCmtxGwvmVC4nJVgUj3XJQ+wseblAkk" +
        "W0+IuT3GKX0CdKFMU4q9aucLYwKBgQDHk3rQ8Ae4ci4oj+MehRI29SNpcXG6OHbr" +
        "Z2EdsgqiFC1o/qv0269jtmCP7IqkGMdhTQrVetTHjZNZJH2bvUZ4o/0YT2+TTFPI" +
        "kTb2/a0txUTBTKrbnAdXh/iPFZAGvBROEDN0MNKo/vGAfi0K836DeTyBIaYongm6" +
        "6Rn6pwnUTQKBgBveVaougfoxAhIbSrWuISCH8xjsE6nSA+G/Aj5Uwq8u1TzgVlWx" +
        "kHLIgQVZt0sImfSufJ/kr7eJt42WgRJSoAmedC4mCBSbh8bxI+lEne+MC5TS9UDi" +
        "/Ly0c/1cL8vQna93ScEcO4YMbJ97U1NBdyvx+eR4U/C89lDJ8YGHa9gzAoGAQ6sY" +
        "sHFCXOKyDeTDoFyEUYgKqrzhT7/HaofR4Oy2OEBZKUl4anx2WnvC/+m3FG6mY7Jo" +
        "ovuT29mABXCe+khR9aO8tBpy/WGa4t2B4nse1e8WIehp4i5kOuSKfZFVFUN+Kv3J" +
        "RHMtakmO/v9JLHZlBhT8U9hh61GygOJ6gYdTiN0CgYAFz9iPy/xqLOUwiTNp3Imz" +
        "hdZo9ol3Qlr9CfMWMFHqRA5AyYvly9ZzxTpUCpSA+qz6OXqAjJ0bhGQxW2KHpmcT" +
        "yNGOPPca2vCaW8Mb1NTQueXpUBqX7alIkrRjUUyULteLb8FtyYl7mR3TVIu3FoO5" +
        "anNwDZ+2y7R9WUEiOzY3NA==";
    
    public static void main(String[] args) {
        try {
            System.out.println("=" + "=".repeat(99));
            System.out.println("测试RSA加密解密循环");
            System.out.println("=" + "=".repeat(99));
            
            // 解析证书和私钥
            byte[] certBytes = Base64.getDecoder().decode(CERT_BASE64);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(
                new ByteArrayInputStream(certBytes)
            );
            PublicKey publicKey = cert.getPublicKey();
            
            byte[] privateKeyBytes = Base64.getDecoder().decode(PRIVATE_KEY_PEM);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            
            // 构造测试数据（模拟AES密钥填充到256字节）
            byte[] testData = new byte[256];
            testData[0] = 0x00;
            byte[] testKey = "d18b48d47c664dc697ae620dc463ac556ce657ce57f45bc4e46177ad751db597".getBytes();
            System.arraycopy(testKey, 0, testData, 1, Math.min(32, testKey.length));
            
            System.out.println("\n原始数据(前64字节):");
            System.out.println(bytesToHex(Arrays.copyOf(testData, 64)));
            
            // RSA加密
            Cipher encryptCipher = Cipher.getInstance("RSA/ECB/NoPadding");
            encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encrypted = encryptCipher.doFinal(testData);
            
            System.out.println("\nRSA加密后(256字节):");
            System.out.println(bytesToHex(encrypted));
            
            // RSA解密
            Cipher decryptCipher = Cipher.getInstance("RSA/ECB/NoPadding");
            decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] decrypted = decryptCipher.doFinal(encrypted);
            
            System.out.println("\nRSA解密后(前64字节):");
            System.out.println(bytesToHex(Arrays.copyOf(decrypted, 64)));
            
            // 验证
            if (Arrays.equals(testData, decrypted)) {
                System.out.println("\n✅ 加密解密循环成功！密钥对完全匹配！");
            } else {
                System.out.println("\n❌ 加密解密循环失败！数据不匹配！");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}


